package com.ai.trickycards.ui.dialog

import android.app.Dialog
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.GradientDrawable
import android.os.Bundle
import android.util.Log
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.viewpager2.widget.ViewPager2
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
import com.ai.trickycards.R
import com.ai.trickycards.databinding.AdapterRaiseItemBinding
import com.ai.trickycards.databinding.DialogRaiseInBinding
import com.ai.trickycards.entity.enumeration.GameMode
import com.ai.trickycards.entity.enumeration.PokerRankEnum
import com.ai.trickycards.ui.adapter.BaseRecyclerAdapter
import com.ai.trickycards.ui.adapter.BaseViewHolder
import kotlin.math.absoluteValue

class RaiseDialog(
    context: Context,
    private val gameMode: GameMode,
    private val isFirstAction: Boolean,
    private val currentCount: Int,
    private val currentRank: PokerRankEnum,
    private val doOnRaise: (count: Int, rank: PokerRankEnum) -> Unit
) : Dialog(context) {

    private val binding by lazy {
        DialogRaiseInBinding.inflate(layoutInflater)
    }

    private lateinit var numberAdapter: PokerAdapter
    private lateinit var cardAdapter: PokerAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("RaiseDialog", "gameMode=$gameMode, isFirstAction=$isFirstAction, currentCount=$currentCount, currentRank=$currentRank")
        setContentView(binding.root)
        setCanceledOnTouchOutside(false)
        setCancelable(false)
        window?.let {
            it.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
            val displayMetrics = context.resources.displayMetrics
            it.attributes.width = (displayMetrics.widthPixels - 48 * displayMetrics.density).toInt()
        }

        val mask = GradientDrawable()
        mask.orientation = GradientDrawable.Orientation.LEFT_RIGHT
        mask.colors = intArrayOf(
            Color.parseColor("#FF060000"),
            Color.parseColor("#E5060000"),
            Color.parseColor("#B2060000"),
            Color.parseColor("#80060000"),
            Color.parseColor("#4D060000"),
            Color.TRANSPARENT,
            Color.TRANSPARENT,
            Color.parseColor("#4D060000"),
            Color.parseColor("#80060000"),
            Color.parseColor("#B2060000"),
            Color.parseColor("#E5060000"),
            Color.parseColor("#FF060000")
        )
        binding.vMaskNumber.background = mask
        binding.vMaskCard.background = mask

        binding.tvCancel.setOnClickListener { dismiss() }
        binding.tvRaise.setOnClickListener { dismiss() }
        val numberList = if (isFirstAction) {
            List(gameMode.playerCount * 4 - gameMode.leastJoker + 1) { Item("${it + gameMode.leastJoker}", true) }
        } else if (currentRank == PokerRankEnum.Joker) {
            List(gameMode.playerCount - gameMode.leastJoker + 1) { Item("${it + gameMode.leastJoker}", true) }
        } else {
            List(gameMode.playerCount * 4 - gameMode.leastPoker + 1) { Item("${it + gameMode.leastPoker}", true) }
        }

        val cardList = if (!isFirstAction && currentRank == PokerRankEnum.Joker) {
            listOf(Item(PokerRankEnum.Joker.text, true))
        } else {
            val list = when (gameMode) {
                GameMode.Royal -> {
                    listOf("T", "J", "Q", "K", "A")
                }

                GameMode.Number -> {
                    listOf("2", "3", "4", "5", "6", "7", "8", "9")
                }

                else -> {
                    listOf("2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A")
                }
            }

            list.let { if (isFirstAction) it + PokerRankEnum.Joker.text else it }.map { Item(it, true) }
        }

        var defaultNumberPosition = 0
        var defaultCardPosition = 0
        val maxRank = if (gameMode == GameMode.Number) PokerRankEnum.Rank9 else PokerRankEnum.RankA
        val maxCount = gameMode.playerCount * if (currentRank == PokerRankEnum.Joker) 1 else 4

        if (isFirstAction) {
            defaultNumberPosition = gameMode.leastPoker - gameMode.leastJoker
        } else {
            for (index in numberList.indices) {
                if (numberList[index].text == "$currentCount") {
                    defaultNumberPosition = index
                    break
                }
            }

            for (index in cardList.indices) {
                if (cardList[index].text == currentRank.text) {
                    defaultCardPosition = index
                    break
                }
            }

            cardList.take(defaultCardPosition).forEach { it.enable = false }

            val defaultCard = PokerRankEnum.valueOfText(cardList[defaultCardPosition].text)
            if (defaultCard.num < maxRank.num) {
                defaultCardPosition++
            } else {
                defaultNumberPosition++
            }

        }

        numberAdapter = setupAdapter(binding.viewPagerNumber, Color.parseColor("#F9222F"), numberList, defaultNumberPosition)
        cardAdapter = setupAdapter(binding.viewPagerCard, Color.parseColor("#1C1B1C"), cardList, defaultCardPosition)

        binding.viewPagerNumber.registerOnPageChangeCallback(object : OnPageChangeCallback() {
            override fun onPageSelected(position: Int) {
                super.onPageSelected(position)
                if (binding.viewPagerNumber.tag != null) {
                    binding.viewPagerNumber.tag = null
                    return
                }

                val item = numberAdapter.getItem(position)
                val num = item.text.toInt()
                if (isFirstAction) {
                    if (num >= gameMode.leastPoker) {
                        if (binding.viewPagerCard.currentItem % cardAdapter.getRealItemCount() == cardAdapter.getRealItemCount() - 1) {
                            setCurrentItem(binding.viewPagerCard, 0)
                        }
                    } else {
                        if (binding.viewPagerCard.currentItem % cardAdapter.getRealItemCount() != cardAdapter.getRealItemCount() - 1) {
                            setCurrentItem(binding.viewPagerCard, cardAdapter.getRealItemCount() - 1)
                        }
                    }
                } else {
                    if (!item.enable) {

                    }
                }
                setRaiseButtonEnabled()
            }
        })

        binding.viewPagerCard.registerOnPageChangeCallback(object : OnPageChangeCallback() {
            override fun onPageSelected(position: Int) {
                super.onPageSelected(position)
                if (binding.viewPagerCard.tag != null) {
                    binding.viewPagerCard.tag = null
                    return
                }
                val item = cardAdapter.getItem(position)
                if (isFirstAction) {
                    val card = PokerRankEnum.valueOfText(item.text)
                    if (card == PokerRankEnum.Joker) {
                        if (binding.viewPagerNumber.currentItem % numberAdapter.getRealItemCount() >= gameMode.leastPoker - gameMode.leastJoker) {
                            setCurrentItem(binding.viewPagerNumber, 0)
                        }
                    } else {
                        if (binding.viewPagerNumber.currentItem % numberAdapter.getRealItemCount() < gameMode.leastPoker - gameMode.leastJoker) {
                            setCurrentItem(binding.viewPagerNumber, gameMode.leastPoker - gameMode.leastJoker)
                        }
                    }
                } else {
                    if (!item.enable) {
                        numberList.forEach { it.enable = false }
                        println("duxl#test: all disabled")
                    } else {
                        val rank = PokerRankEnum.valueOfText(item.text)
                        if (rank == currentRank) {
                            numberList.forEach {
                                it.enable = it.text.toInt() > currentCount
                                println("duxl#test: ${it.text} ${it.enable}")
                            }
                        } else {
                            numberList.forEach { it.enable = true }
                            println("duxl#test: all abled")
                        }
                    }
                    val currentNumPosition = binding.viewPagerNumber.currentItem
                    val positionStart = currentNumPosition - numberAdapter.getRealItemCount()
                    val itemCount = numberAdapter.getRealItemCount() * 2
                    println("duxl#test: currentNumPosition=$currentNumPosition, positionStart=$positionStart, itemCount=$itemCount")
                    numberAdapter.notifyItemRangeChanged(positionStart, itemCount)
                }
                setRaiseButtonEnabled()
            }
        })

        binding.tvRaise.setOnClickListener {
            it.isEnabled = false
            dismiss()
            val count = numberAdapter.getItem(binding.viewPagerNumber.currentItem).text.toInt()
            val rank = PokerRankEnum.valueOfText(cardAdapter.getItem(binding.viewPagerCard.currentItem).text)
            doOnRaise.invoke(count, rank)
        }

    }

    private fun setRaiseButtonEnabled() {
        binding.tvRaise.isEnabled = numberAdapter.getItem(binding.viewPagerNumber.currentItem).enable
                && cardAdapter.getItem(binding.viewPagerCard.currentItem).enable
        if (binding.tvRaise.isEnabled) {
            binding.tvRaise.setTextColor(ContextCompat.getColor(context, R.color.base_black))
            binding.tvRaise.backgroundTintList = null
        } else {
            binding.tvRaise.setTextColor(Color.parseColor("#999999"))
            binding.tvRaise.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#CCCCCC"))
        }
    }

    /**
     * 将ViewPager移动到指定的位置（向左或向右最小移动）
     */
    private fun setCurrentItem(
        viewPager: ViewPager2,
        toRealPosition: Int
    ) {
        val adapter = viewPager.adapter as PokerAdapter
        var toPosition = viewPager.currentItem
        for (i in 1 until adapter.getRealItemCount()) {
            if ((viewPager.currentItem + i) % adapter.getRealItemCount() == toRealPosition) {
                toPosition = viewPager.currentItem + i
                break
            }
            if ((viewPager.currentItem - i) % adapter.getRealItemCount() == toRealPosition) {
                toPosition = viewPager.currentItem - i
                break
            }
        }

        viewPager.tag = "notTouch"
        viewPager.currentItem = toPosition
    }

    private fun setupAdapter(
        viewPager: ViewPager2,
        color: Int,
        items: List<Item>,
        defaultPosition: Int = 0
    ): PokerAdapter {
        val adapter = PokerAdapter(context, color, items)
        viewPager.adapter = adapter
        viewPager.offscreenPageLimit = 9
        viewPager.setPageTransformer { page, position ->
            val absPos = position.absoluteValue
            page.translationX = -position * page.width * 0.86f
            if (absPos > 1) {
                page.scaleY = 0.85f
                page.scaleX = 0.85f
            } else {
                val scale = 1 - absPos * 0.15f
                page.scaleY = scale
                page.scaleX = scale
            }
        }
        viewPager.setCurrentItem(Int.MAX_VALUE / 2 / items.size * items.size + defaultPosition, false)
        return adapter
    }

    private data class Item(var text: String, var enable: Boolean)

    private inner class PokerAdapter(
        private val context: Context,
        private val color: Int,
        private val items: List<Item>
    ) : BaseRecyclerAdapter(R.layout.adapter_raise_item) {
        override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
            val binding = AdapterRaiseItemBinding.bind(holder.itemView)
            val realPosition = getRealPosition(position)
            val item = items[realPosition]
            if (PokerRankEnum.Joker.text == item.text) {
                binding.tvContent.isVisible = false
                binding.vJoker.isVisible = true
            } else {
                binding.tvContent.isVisible = true
                binding.vJoker.isVisible = false
                binding.tvContent.text = item.text
                binding.tvContent.setTextColor(color)
            }
            binding.vMask.isVisible = !item.enable
        }

        private fun getRealPosition(position: Int): Int {
            return position % items.size
        }

        fun getItem(position: Int) = items[getRealPosition(position)]

        override fun getItemCount() = Int.MAX_VALUE

        fun getRealItemCount() = items.size
    }
}